<template>
  <div class="container">
    <div class="monitor">
      <video class="video" ref="video" muted autoplay @play="onPlay"></video>
    </div>

    <div class="controls">
      <el-button
        type="primary"
        v-loading="recordControlBool"
        @click="recordControl"
      >
        {{ recorderState === "inactive" ? "开始录制" : "完成录制" }}
      </el-button>
      <el-button type="danger" v-loading="takePictureBool" @click="takePicture">
        拍照
      </el-button>
      <el-button type="danger" @click="initVideo"> 开启摄像头 </el-button>
      <el-button type="danger" @click="stopVideo"> 关闭摄像头 </el-button>
    </div>
    <div class="tips" v-if="recorder">已录制{{ recorder.duration }}秒</div>
  </div>
</template>

<script>
import { exportVideo, download } from "@/utils/utils.js";
export default {
  name: "monitor",
  data() {
    return {
      recorderState: "inactive",
      recordControlBool: true,
      takePictureBool: true,
      recorder: null,
    };
  },
  methods: {
    // 播放视频
    initVideo() {
      window.navigator.mediaDevices
        .getUserMedia({
          video: true,
        })
        .then((stream) => {
          this.$refs.video.srcObject = stream;
        });
    },

    stopVideo() {
      this.$refs.video.srcObject.getTracks().forEach((_) => _.stop());
      this.takePictureBool = true;
      this.recordControlBool = true;
    },

    // 视频可以播放了才给操作
    onPlay() {
      this.recordControlBool = false;
      this.takePictureBool = false;
    },

    // 拍照
    takePicture() {
      let canvas = document.createElement("canvas");
      let video = this.$refs.video;
      let videoStyle = getComputedStyle(video);
      canvas.width = parseInt(videoStyle.width);
      canvas.height = parseInt(videoStyle.height);
      let ctx = canvas.getContext("2d");
      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
      let url = canvas.toDataURL();
      download(url, "jpg");
      this.$notify({
        title: "系统消息",
        message: "拍照成功",
        type: "success",
      });
    },

    // 开始、结束录制
    recordControl() {
      if (!this.recorder) {
        this.recordControlBool = true;
        this.createRecorder();
        this.recorder.myStart(1000);
      } else if (this.recorder.state === "recording") {
        this.recorder.myStop();
      }
    },

    // 创建MediaRecorder对象
    createRecorder() {
      let stream = this.$refs.video.captureStream();
      const options = { mimeType: "video/webm;codecs=vp8" };
      let recorder = new MediaRecorder(stream, options);
      recorder.myStart = () => {
        recorder.start(1000);
        this.$notify({
          title: "系统消息",
          message: "开始录制",
          type: "warning",
        });
        recorder.duration = 0;
        recorder.timer = setInterval(() => {
          recorder.duration += 1;
          this.$forceUpdate();
        }, 1000);
      };
      recorder.myStop = () => {
        recorder.stop();
        this.$notify({
          title: "系统消息",
          message: "完成录制",
          type: "success",
        });
        clearInterval(recorder.timer);
      };
      recorder.chunks = [];
      recorder.ondataavailable = (e) => {
        recorder.chunks.push(e.data);
      };
      recorder.onstart = (e) => {
        this.recorderState = recorder.state;
        this.recordControlBool = false;
      };
      recorder.onstop = (e) => {
        this.recorderState = recorder.state;

        let blob = new Blob(recorder.chunks, {
          type: "video/webm;codecs=vp8;",
        });
        exportVideo(blob);
        this.recorder = null;
      };
      this.recorder = recorder;
    },
  },
  mounted() {},
};
</script>

<style lang="scss" scoped>
.container {
  .monitor {
    width: 1200px;
    height: 675px;
    margin: 30px auto 0;
    border: 5px solid rgb(115, 101, 177);
    .video {
      width: 100%;
      height: 100%;
      background: #333;
    }
  }
  .controls {
    margin-top: 20px;
    display: flex;
    justify-content: center;
    button {
      margin: 0 5px;
    }
  }

  .tips {
    text-align: center;
    color: rgba(0, 0, 0, 0.65);
  }
}
</style>
